package com.example.androidproject.utils;

import android.os.Handler;
import android.text.TextUtils;

import com.alibaba.sdk.android.oss.ClientException;
import com.alibaba.sdk.android.oss.ServiceException;
import com.alibaba.sdk.android.oss.callback.OSSCompletedCallback;
import com.alibaba.sdk.android.oss.callback.OSSProgressCallback;
import com.alibaba.sdk.android.oss.model.PutObjectRequest;
import com.alibaba.sdk.android.oss.model.PutObjectResult;
import com.example.androidproject.MyApp;
import com.example.androidproject.R;
import com.example.androidproject.data.Config;
import com.example.androidproject.widget.interfaces.StringCallback;
import com.hyg.common.utils.CrashHandler;
import com.hyg.common.utils.DateUtils;
import com.hyg.common.utils.DeviceIdUtil;
import com.hyg.common.utils.LogManager;
import com.hyg.common.utils.LogUtils;
import com.hyg.common.utils.SPUtils;
import com.hyg.common.utils.language.LanguageUtil;

import java.io.File;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * FileName: LogUploadUtil
 * Author: huangyuguang
 * Date: 2022/9/30
 * Description: 日志管理
 */
public class LogUploadUtil {
    private static final String TAG = "LogUploadUtil";
    private static long uploadBigFileTime = 0;//大文件防止频繁上传

    private static Set<String> logNames = new HashSet<>();
    private static Handler mHandler = new Handler(MyApp.getApp().getMainLooper());
    private static Runnable logRunnable = () -> SPUtils.putStringSet("logUploadNames",logNames);

    private synchronized static void saveUploadNames(){
        mHandler.removeCallbacks(logRunnable);
        mHandler.postDelayed(logRunnable,1000);
    }

    /**
     * 开机自动上传日志频率高
     */
    public static void autoUploadLogs(){
        if(logNames == null) logNames = new HashSet<>();
        logNames.clear();
        //fileNames已经上传成功的文件名
        Set<String> oldFileNames = SPUtils.getStringSet("logUploadNames",null);
//        uploadLogs(Conts.LOG_PATH,oldFileNames);
//        uploadLogs(Conts.CRASH_LOG_PATH,oldFileNames);
    }

    /**
     * 手动触发上传
     */
    public static void uploadLogsByClick(){
        autoUploadLogs();
        //一分钟内只上传一次大文件
        long nowTime = System.currentTimeMillis();
        if(nowTime - uploadBigFileTime > 60000){
            uploadBigFileTime = nowTime;
            String localFile = "/sdcard/deyi/download/log.s3db";
//            FtpUtil.INSTANCE.downloadFile("/log/log.s3db",localFile,s -> {
//                if(s.startsWith("ok")) uploadLog(new File(localFile),null);
//                return null;
//            });
        }
    }

    private static void uploadLogs(String logPath, Set<String> oldFileNames){
        File dFile = new File(logPath);
        if(!dFile.exists()) return;
        File[] files = dFile.listFiles();
        if(files != null && files.length > 0){
            for(File file: files){
                if(file.isFile()){
                    boolean canUpload = true;
                    if(oldFileNames != null){
                        for(String name: oldFileNames){//判断这个file是否已经上传了
                            if(name.equals(file.getName())){
                                canUpload = false;//已经上传过了，不能再重复上传
                                logNames.add(name);//本地存在的文件且已经上传成功的
                                break;
                            }
                        }
                    }
                    //没上传过的文件，或者是可以追加内容的api文件，就可以上传到服务器
                    if(canUpload || file.getName().equals(LogManager.getInstance().getApiFileName())){
                        uploadLog(file, str -> {
                            if(!TextUtils.isEmpty(str)){
                                logNames.add(str);
                                saveUploadNames();//上传成功了保存已上传的文件名
                            }
                        });
                    }
                }
            }
            saveUploadNames();//更新本地存在的且已上传的文件名
        }
    }

    private static void uploadLog(File logFile, StringCallback callback){
        String dirName = "logs";
        String uploadFilePath = logFile.getAbsolutePath();
        if(uploadFilePath.contains("crashLogs")){
            dirName = "crashLogs";
        }
        String objectKey = String.format("%s/%s/%s/%s", LanguageUtil.getStringToEnglish(MyApp.getApp(),R.string.app_name), DeviceIdUtil.getDeviceId(MyApp.getApp()),dirName,logFile.getName());
        PutObjectRequest put = new PutObjectRequest(Config.OSS_BUCKET, objectKey, logFile.getAbsolutePath());

        put.setProgressCallback(new OSSProgressCallback<PutObjectRequest>() {
            @Override
            public void onProgress(PutObjectRequest request, long currentSize, long totalSize) {
//                LogUtils.d("PutObject", "currentSize: " + currentSize + " totalSize: " + totalSize);
            }
        });

        MyApp.oss.asyncPutObject(put, new OSSCompletedCallback<PutObjectRequest, PutObjectResult>() {
            @Override
            public void onSuccess(final PutObjectRequest request, PutObjectResult result) {
                String url = MyApp.oss.presignPublicObjectURL(Config.OSS_BUCKET, objectKey);
                LogUtils.d(TAG, String.format("log日志上传成功 -> %s",url));
                logReport(url);
                if(callback != null){
                    callback.callback(logFile.getName());
                }
            }

            @Override
            public void onFailure(PutObjectRequest request, ClientException clientExcepion, ServiceException serviceException) {
                LogUtils.d(TAG, "log日志上传失败");
                // 请求异常
                if (clientExcepion != null) {
                    // 本地异常如网络异常等
                    clientExcepion.printStackTrace();
                }
                if (serviceException != null) {
                    // 服务异常
                    serviceException.printStackTrace();
                }
                if(callback != null){
                    callback.callback(null);
                }
            }
        });
    }

    private static void logReport(String url){
//        RetrofitHelper.logReport(url)
//                .compose(RxUtil.rxSchedulerHelper())
//                .subscribe(new APICallback<Object>() {
//                    @Override
//                    public void onSuccess(Object response) {
//
//                    }
//
//                    @Override
//                    public void onError(Throwable e) {
////                        super.onError(e);
//                    }
//                });
    }
}
